package com.health.agent.server.controller;

import com.health.agent.server.service.LoggingAdvisor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.PromptChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.QuestionAnswerAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

import java.time.LocalDate;

import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY;


/**
 * @author lemon
 * @version 1.0
 * @description:
 */
@RestController
public class OpenAiController {

    private final ChatClient chatClient;
    @Autowired
    private ChatMemory inMemoryChatMemory;

    public OpenAiController(ChatClient.Builder chatClientBuilder, VectorStore vectorStore, ChatMemory chatMemory) {
        this.chatClient = chatClientBuilder
                .defaultSystem("""
					   你是医院的患者聊天支持代理。
					   回答尽量简短。
                       你正在通过聊天系统与患者互动。
                       在提供医生的列表之前，您必须始终
                       从用户处获取以下信息：病状。
                       在询问患者之前，你需要检查消息历史记录以获取此信息。
                       你可以根据患者的病状查询到相对应的医生列表。
                       在进行挂号和取消挂号之前,需要获得医生姓名和患者姓名。
                       今天的日期是 {current_date}.
					""")
                .defaultAdvisors(
                        new PromptChatMemoryAdvisor(chatMemory),
                        new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults()), // RAG
                        new LoggingAdvisor())
                .defaultFunctions("getMedicList", "doRegister") // FUNCTION CALLING
                .build();
    }

    @GetMapping(value = "/chat/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> generateStreamAsString(@RequestParam(value = "message", defaultValue = "讲个励志语") String message) {

        //获取用户id
        String userId = "1";

        Flux<String> content = chatClient.prompt()
                .system(s -> s.param("current_date", LocalDate.now().toString()))
                .user(message)
                .advisors(a -> a.param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 100))
                .stream()
                .content();
        return  content
                .concatWith(Flux.just("[complete]"));
    }



}
